﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using RaptorEngine.Components;
using RaptorEngine.Components.CollidableComponent;

namespace RaptorEngine.Managers
{
	public class SceneManager
	{
		
		private Stack<Scene> _scenes;
        public Stack<Scene> Scenes { get { return _scenes; } }

	    public bool IsPaused { get; set; }

	    private int _sceneIndex;

		public SceneManager()
		{
			_scenes = new Stack<Scene>();
		}

		public void PushScene(Scene scene)
		{
			_scenes.Push(scene);
		    _sceneIndex++;
		}

		public Scene PopScene()
		{
		   DecreaseSceneIndex();
			return _scenes.Pop();
		}

		public Scene PeekScene()
		{
			return _scenes.Peek();
		}
		
		public void LoadContent()
		{
		}

        public void StartCurrentScene()
        {
            _scenes.Peek().IsActive = true;
        }

        public void StopCurrentScene()
        {
            _scenes.Peek().IsActive = false;
        }

        public void HideCurrentScene()
        {
            _scenes.Peek().IsVisible = false;
        }

        public void ShowCurrentScene()
        {
            _scenes.Peek().IsVisible = true;
        }
		
        public void RemoveCurrentScene()
        {
            _scenes.Pop();
           DecreaseSceneIndex();
        }
        private void DecreaseSceneIndex()
        {
            _sceneIndex--;
            if (_sceneIndex < 0) _sceneIndex = 0;
        }

		public void Update(GameTime gt)
		{
            for (_sceneIndex = 0; _sceneIndex < _scenes.Count; _sceneIndex++)
            {
                Scene scene = _scenes.ToArray()[_sceneIndex];

                if (scene.IsActive)
                {
                    // Temp
                    GameEngine.Instance.Network.Update(gt);

                    //Controllable
                    List<Controllable> controllables = scene.GetControllableComponents();
                    foreach (Controllable controllable in controllables)
                    {
                        controllable.Update(gt);
                    }

                    scene.Update();
					//Moveable
					GameEngine.Instance.Physics.Update(gt, scene);
                }
                foreach (Entity entity in scene.Entities)
                {
                    entity.SendChangeMessage();
                }
            }
		}

	    internal void Pause(Scene pauseScene)
        {
            _scenes.Peek().IsActive = false;
            pauseScene.IsActive = true;
            pauseScene.IsVisible = true;
            _scenes.Push(pauseScene);
            IsPaused = true;
        }

        internal void UnPause()
        {
            PeekScene().IsVisible = false;
            PeekScene().IsActive = false;
            PopScene();
            PeekScene().IsActive = true;
            IsPaused = false;
        }


		internal List<Collidable> GetCollidableComponents()
		{
			List<Collidable> collidables = new List<Collidable>();

			foreach (Scene scene in Scenes)
			{
				collidables.AddRange(scene.GetCollidableComponents());
			}
			return collidables;
		}

		internal List<Movable> GetMoveableComponents()
		{
			List<Movable> movables = new List<Movable>();
			
			foreach (Scene scene in Scenes)
			{
				movables.AddRange(scene.GetMoveableComponents());
			}
			return movables;
		}
	}
}
